package com.sharemarking.wa.platform.service;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sharemarking.wa.common.Page;
import com.sharemarking.wa.common.ResponseParams;
import com.sharemarking.wa.common.entity.*;
import com.sharemarking.wa.common.eum.OrderOperateTypeEum;
import com.sharemarking.wa.common.exception.DriverException;
import com.sharemarking.wa.common.exception.OrgException;
import com.sharemarking.wa.common.exception.RequestException;
import com.sharemarking.wa.platform.dto.orderCommon.OrderInfoDto;
import com.sharemarking.wa.platform.dto.orderCommon.WasteListDto;
import com.sharemarking.wa.platform.dto.receiptManagement.*;
import com.sharemarking.wa.platform.mapper.*;
import com.sharemarking.wa.platform.service.OrderCommonFactory.OrderCommonFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import javax.servlet.http.HttpServletRequest;
import java.text.SimpleDateFormat;
import java.util.*;

import static com.sharemarking.wa.common.SysHttpStatus.*;

/**
 * @author dxy
 */
@Service
public class ReceiptManagementService {
    @Autowired
    private HttpServletRequest request;
    @Autowired
    private SecurityService ss;
    @Autowired
    private ReceiptManagementMapper receiptManagementMapper;
    @Autowired
    private ReceiptHeadMapper receiptHeadMapper;
    @Autowired
    private ReceiptMapper receiptMapper;
    @Autowired
    private ReceiptPayRecordMapper receiptPayRecordMapper;
    @Autowired
    private MemberMapper memberMapper;
    @Autowired
    private OrderCommonMapper orderCommonMapper;
    @Autowired
    private DriverVerifyMapper driverVerifyMapper;
    @Autowired
    private InvoiceMapper invoiceMapper;
    @Autowired
    private OrderCommonFactory orderCommonFactory;
    @Autowired
    private OrderMapper orderMapper;

    Map<Integer, List<Integer>> stateMap;

    public ReceiptManagementService() {
        stateMap = new HashMap<>();
        //产废端状态码
        List<Integer> pwStateList = Arrays.asList(-1, 0, 1, 3, 4, 5, 7, 8, 9, 10, 11);
        //经营端状态码
        List<Integer> mStateList = Arrays.asList(-1, 3, 11, 4, 5, 7, 8, 9);
        //司机端状态码
        List<Integer> drStateList = Arrays.asList(-1, 7, 8, 9);
        //调度员和运输单位端状态码
        List<Integer> dpStateList = Arrays.asList(-1, 6, 7, 8, 9);

        stateMap.put(0, pwStateList);
        stateMap.put(1, mStateList);
        stateMap.put(2, drStateList);
        stateMap.put(3, dpStateList);
        stateMap.put(4, dpStateList);
    }

    public ResponseParams<?> getOrderLists() throws Exception {
        Integer memberId = ss.getCurrentUserId();

        int pageIndex = Integer.parseInt(StringUtils.isEmpty(request.getParameter("pageIndex")) ? "1" : request.getParameter("pageIndex"));
        int pageSize = Integer.parseInt(StringUtils.isEmpty(request.getParameter("pageSize")) ? "10" : request.getParameter("pageSize"));

        Map<String, Object> params = new HashMap<>();
        params.put("pageIndex", (pageIndex - 1) * pageSize);
        params.put("pageSize", pageSize);
        params.put("memberId", memberId);

        Integer role = memberMapper.getRoleByMemberId(memberId);

        if (role == 1 || role == 0) {
            //经营商 和 产废端
            Integer examState = orderCommonMapper.isOrgVerify(memberId);
            if (examState == null || examState != 1) {
                if (role == 0) {
                    throw OrgException.create(ResponseParams.error(UN_P_ORG_VERIFY));
                } else if (role == 1) {
                    throw OrgException.create(ResponseParams.error(UN_M_ORG_VERIFY));
                }
            }
        } else if (role == 2) {
            //司机端
            DriverVerify driverVerify = driverVerifyMapper.selectOne(new QueryWrapper<DriverVerify>().eq("member_id", memberId).eq("exam_state", 1));
            if (driverVerify == null) {
                throw DriverException.create(ResponseParams.error(UN_DRIVER_VERIFY));
            } else {
                params.put("driverId", driverVerify.getMemberId());
            }
        }
        params.put("role", role);
        params.put("state", 9);
        List<com.sharemarking.wa.platform.dto.orderCommon.OrderListDto> orderList = orderCommonFactory.getOrderList(params);
        if (role == 4) {
            for (com.sharemarking.wa.platform.dto.orderCommon.OrderListDto tem : orderList)
                tem.setOperate(null);
        }

        List<OrderDto> list = new ArrayList<>();
        for (com.sharemarking.wa.platform.dto.orderCommon.OrderListDto i : orderList) {
            params.put("code", i.getCode());
            OrderInfoDto a = orderCommonFactory.getOrderInfo(params);
            OrderDto dto = new OrderDto();
            dto.setId(a.getId());
            dto.setCode(i.getCode());
            dto.setLoadingAddress(a.getLoadingAddress());
            dto.setUnLoadingAddress(a.getUnLoadingAddress());
            dto.setTransportFees(a.getTransportFees());
            dto.setPayType(
                    !StringUtils.isEmpty(invoiceMapper.selectOne(new QueryWrapper<Invoice>().eq("transaction_code", a.getCode()))) &&
                            invoiceMapper.selectOne(new QueryWrapper<Invoice>().eq("transaction_code", a.getCode())).getType() == 1 ? "月结" : "已付");
            if (
                    receiptManagementMapper.isReceipt(i.getCode()) == 1
            )
                list.add(dto);
        }
        return ResponseParams.ok(new Page<>(list, pageIndex, pageSize, orderCommonMapper.getListTotal(params), orderList.size() == pageSize));
    }

    public ResponseParams<?> getOrders() throws Exception {
        Integer memberId = ss.getCurrentUserId();
        String code = request.getParameter("code");

        if (StringUtils.isEmpty(code)) {
            throw RequestException.create(ResponseParams.requiredParamsIsMissing("code"));
        }
        Map<String, Object> params = new HashMap<>();
        Integer role = memberMapper.getRoleByMemberId(memberId);
        params.put("code", code);
        params.put("role", role);
        params.put("memberId", memberId);
        OrderInfoDto i = orderCommonFactory.getOrderInfo(params);
        if (role == 4)
            i.setOperate(null);

        OrderListsDto dto = new OrderListsDto();
        BeanUtils.copyProperties(i, dto);
        dto.setCarWeight(Integer.valueOf(i.getCarWeight())*1000);
        dto.setArrivalTime(new Date(i.getArrivalTime()));
        dto.setPayRecordId(receiptManagementMapper.getPayRecordIdByCode(i.getCode()));
        dto.setAcceptDate(orderMapper.selectById(i.getId()).getCreateDate());
        dto.setCreateDate(new Date(i.getCreateDate()));
        dto.setCompleteTime(new Date(i.getCompleteTime()));

        return ResponseParams.ok(dto);
    }

    public ResponseParams<?> getOrderList() throws Exception {
        Integer memberId = ss.getCurrentUserId();
        String state = request.getParameter("state");
        int pageIndex = Integer.parseInt(StringUtils.isEmpty(request.getParameter("pageIndex")) ? "1" : request.getParameter("pageIndex"));
        int pageSize = Integer.parseInt(StringUtils.isEmpty(request.getParameter("pageSize")) ? "10" : request.getParameter("pageSize"));

        Map<String, Object> params = new HashMap<>();
        params.put("pageIndex", (pageIndex - 1) * pageSize);
        params.put("pageSize", pageSize);
        params.put("memberId", memberId);

        if (!StringUtils.isEmpty(state)) {
            params.put("state", state);
        }

        List<OrderListDto> list = receiptManagementMapper.getOrderList(params);
//        for (OrderListDto o : list) {
//            o.setDescription(receiptManagementMapper.getAllAddressByCode(o.getCode()));
//        }

        return ResponseParams.ok(new Page<>(list, pageIndex, pageSize, receiptManagementMapper.getOrderListTotal(params), list.size() == pageSize));
    }

    public ResponseParams<?> getReceiptList() throws Exception {
        Integer memberId = ss.getCurrentUserId();
        Integer role = memberMapper.getRoleByMemberId(memberId);
        int pageIndex = Integer.parseInt(StringUtils.isEmpty(request.getParameter("pageIndex")) ? "1" : request.getParameter("pageIndex"));
        int pageSize = Integer.parseInt(StringUtils.isEmpty(request.getParameter("pageSize")) ? "10" : request.getParameter("pageSize"));

        Map<String, Object> params = new HashMap<>();
        params.put("pageIndex", (pageIndex - 1) * pageSize);
        params.put("pageSize", pageSize);
        params.put("memberId", memberId);


        params.put("state", 1);

        List<ReceiptListDto> list = receiptManagementMapper.getReceiptList(params);

        List<ReceipDto> receiptList = new ArrayList<>();

        for (ReceiptListDto a : list) {
            ReceipDto dto = new ReceipDto();
            Map<String, Object> param = new HashMap<>();
            param.put("code", receiptManagementMapper.getCodeByReceiptId(a.getId()));
            param.put("role", role);
            param.put("memberId", memberId);
            OrderInfoDto i = orderCommonFactory.getOrderInfo(param);
            if (!StringUtils.isEmpty(i)) {
                dto.setAmount(i.getTransportFees());
                dto.setCode(i.getCode());
                dto.setLoadingAddress(i.getLoadingAddress());
                dto.setUnLoadingAddress(i.getUnLoadingAddress());
                dto.setType("电子发票");
                dto.setJourney(i.getDistance());
            }
            if (!StringUtils.isEmpty(receiptManagementMapper.getPayRecordIdByCode(i.getCode())))
                receiptList.add(dto);
        }
        return ResponseParams.ok(new Page<>(receiptList, pageIndex, pageSize, receiptManagementMapper.getReceiptListTotal(params), list.size() == pageSize));
    }


    public ResponseParams<?> getReceiptDetail() throws Exception {
        Integer memberId = ss.getCurrentUserId();
        String code = request.getParameter("code");

        if (StringUtils.isEmpty(code)) {
            throw RequestException.create(ResponseParams.requiredParamsIsMissing("code"));
        }
        Map<String, Object> params = new HashMap<>();
        Integer role = memberMapper.getRoleByMemberId(memberId);
        params.put("code", code);
        params.put("role", role);
        params.put("memberId", memberId);
        OrderInfoDto i = orderCommonFactory.getOrderInfo(params);
        if (role == 4)
            i.setOperate(null);

        ReceipDto dto = new ReceipDto();

        ReceiptHeadDto receiptHead = receiptManagementMapper.getReceiptHead(memberId);

        dto.setAmount(i.getTransportFees());
        dto.setCode(i.getCode());
        dto.setLoadingAddress(i.getLoadingAddress());
        dto.setUnLoadingAddress(i.getUnLoadingAddress());
        dto.setType("电子发票");
        dto.setJourney(i.getDistance());
        if (!StringUtils.isEmpty(receiptHead)) {
            dto.setReceiptHead(receiptHead.getName());
            dto.setMobile(receiptHead.getMobile());
            dto.setTaxNumber(receiptHead.getTaxNumber());
            dto.setEmail(receiptHead.getEmail());
        }
        dto.setPayRecordId(receiptManagementMapper.getPayRecordIdByCode(i.getCode()));

        return ResponseParams.ok(dto);
    }


    public ResponseParams<?> getReceiptHead() throws Exception {
        Integer memberId = ss.getCurrentUserId();

        ReceiptHeadDto receiptHead = receiptManagementMapper.getReceiptHead(memberId);

        return ResponseParams.ok(receiptHead);
    }


    public ResponseParams<?> addReceiptHead() throws Exception {
        Integer memberId = ss.getCurrentUserId();

        String name = request.getParameter("name");
        String mobile = request.getParameter("mobile");
        String taxNumber = request.getParameter("taxNumber");
        String email = request.getParameter("email");
        String headId = request.getParameter("headId");

        if (StringUtils.isEmpty(name)) {
            throw RequestException.create(ResponseParams.requiredParamsIsMissing("name"));
        }

        if (StringUtils.isEmpty(mobile)) {
            throw RequestException.create(ResponseParams.requiredParamsIsMissing("mobile"));
        }

        if (StringUtils.isEmpty(taxNumber)) {
            throw RequestException.create(ResponseParams.requiredParamsIsMissing("taxNumber"));
        }

        if (StringUtils.isEmpty(email)) {
            throw RequestException.create(ResponseParams.requiredParamsIsMissing("email"));
        }

        ReceiptHead receiptHead = new ReceiptHead();
        receiptHead.setName(name);
        receiptHead.setMemberId(memberId);
        receiptHead.setTaxNumber(taxNumber);
        receiptHead.setAddresseeMobile(mobile);
        receiptHead.setAddresseeEmail(email);
        receiptHead.setCreateDate(new Date());
        if (StringUtils.isEmpty(headId)) {
            receiptHeadMapper.insert(receiptHead);
        } else {
            receiptHead.setId(Integer.valueOf(headId));
            receiptHead.setUpdateDate(new Date());
            receiptHeadMapper.updateById(receiptHead);
        }

        Map<String, Integer> params = new HashMap<>();
        params.put("headId", receiptHead.getId());
        return ResponseParams.ok(params);
    }

    @Transactional(rollbackFor = Exception.class)
    public ResponseParams<?> submitReceipt() throws Exception {
        Integer memberId = ss.getCurrentUserId();
        String payRecordIdList = request.getParameter("payRecordIdList");
        String name = request.getParameter("name");
        String mobile = request.getParameter("mobile");
        String email = request.getParameter("email");
        String taxNumber = request.getParameter("taxNumber");


        if (StringUtils.isEmpty(payRecordIdList)) {
            throw RequestException.create(ResponseParams.requiredParamsIsMissing("payRecordIdList"));
        }
        if (StringUtils.isEmpty(name)) {
            throw RequestException.create(ResponseParams.requiredParamsIsMissing("name"));
        }
        if (StringUtils.isEmpty(mobile)) {
            throw RequestException.create(ResponseParams.requiredParamsIsMissing("mobile"));
        }
        if (StringUtils.isEmpty(email)) {
            throw RequestException.create(ResponseParams.requiredParamsIsMissing("email"));
        }
        if (StringUtils.isEmpty(taxNumber)) {
            throw RequestException.create(ResponseParams.requiredParamsIsMissing("taxNumber"));
        }

        List<Integer> recordList;
        try {
            recordList = JSON.parseArray(payRecordIdList, Integer.class);
        } catch (Exception e) {
            throw RequestException.create(ResponseParams.isDataError("JSON格式错误"));
        }

        //计算发票总额
        if (recordList.size() == 0) {
            throw RequestException.create(ResponseParams.requiredParamsIsMissing("payRecordIdList"));
        }


        Integer totalAmount = receiptManagementMapper.getTotalAmount(recordList);
        Receipt receipt = new Receipt();
        receipt.setAmount(totalAmount);
        receipt.setMemberId(memberId);
        receipt.setState(0);
        receipt.setType(0);
        receipt.setName(name);
        receipt.setAddresseeMobile(mobile);
        receipt.setAddresseeEmail(email);
        receipt.setTaxNumber(taxNumber);
        receipt.setCreateDate(new Date());
        receiptMapper.insert(receipt);

        for (Integer i : recordList) {
            ReceiptPayRecord rpr = new ReceiptPayRecord();
            rpr.setPayRecordId(i);
            rpr.setReceiptId(receipt.getId());
            receiptPayRecordMapper.insert(rpr);

            //更改支付订单状态
            PayRecord p = new PayRecord();
            p.setIsReceipt(1);
            p.setId(i);
            p.setUpdateDate(new Date());
            receiptManagementMapper.updatePayRecordReceipt(p);
        }


        return ResponseParams.ok(null);
    }


}
